import sys
import os
import logging
import argparse
import puzautils.table.utils as pzt

class ParserProcesser:
    # ========================
    actions = {}
    error_msg = {}
    asks = {}
    # ========================
    asks['table_length'] = ['input_filename','mode']
    actions['table_length'] = pzt.table_length
    asks['table_verify'] = ['input_filename','mode']
    actions['table_verify'] = pzt.table_verify
    asks['table_structure'] = ['input_filename', 'mode']
    actions['table_structure'] = pzt.table_structure
    asks['table_rows'] =['input_filename', 'mode', 'start_n', 'end_n']
    actions['table_rows'] = pzt.table_show_rows
    asks['table_merge'] = ['output_filename', 'mode', 'block_number', 'tables']
    actions['table_merge'] = pzt.table_merge
    asks['table_show'] = ['input_filename', 'mode']
    actions['table_show'] = pzt.table_show
    asks['table_filter'] = ['input_filename', 'output_filename', 'field_name', 'operator', 'output_format', 'block_number']
    actions['table_filter'] = pzt.table_filter
    asks['table_make_index'] = ['input_filename', 'output_filename', 'field_name', 'output_format', 'index_mode']
    actions['table_make_index'] = pzt.table_make_index
    asks['table_seek_by_index'] = ['input_filename', 'index_filename', 'query']
    actions['table_seek_by_index'] = pzt.table_seek_by_index
    asks['table_compress'] = ['input_filename', 'output_filename', 'block_number']
    actions['table_compress'] = pzt.table_compress
    asks['table_decompress'] = ['input_filename', 'output_filename']
    actions['table_decompress'] = pzt.table_decompress
    # ======================== 
    error_msg['input_filename'] = "Please specify the input filename by using [-i] option."
    error_msg['index_filename'] = "Please specify the index filename by using [--index] option."
    error_msg['output_filename'] = "Please specify the output filename by using [-o] option."
    error_msg['field_name'] = "Please specify the field name of the table by using [-f] option."    
    error_msg['query'] = "Please specify the query name by using [-q] option."
    error_msg['no_action'] = "Please specify the action by using [-a] option."

    @staticmethod
    def ProcessActions(parser, args):
        if args.action:
            required_asks = ParserProcesser.asks[args.action]
            argument_list = []
            for ask in required_asks:
                if getattr(args, ask) == None:
                    parser.error(ParserProcesser.error_msg[ask])
                    sys.exit()
                else:
                    argument_list.append(getattr(args, ask))
                    logging.info('Parameter: ' + ask + ':\t' + str(getattr(args, ask)))
            argument_list = tuple(argument_list)
            ParserProcesser.actions[args.action](argument_list[0], *argument_list[1:])
        else:
            ParserProcesser.error_msg['no_action'] = ParserProcesser.error_msg['no_action'] + '\nPossible actions:'
            for action in ParserProcesser.actions.keys():
                ParserProcesser.error_msg['no_action'] = ParserProcesser.error_msg['no_action'] + '\n' +str(action)
            parser.error(ParserProcesser.error_msg['no_action'])
        return 

## test programs ##
if __name__ == '__main__':   
    parser = argparse.ArgumentParser(description='The wrapper program for PuzaUtils.')
    parser.add_argument('-a','--action', dest ='action', default='', help = 'the action taken for the program.')
    parser.add_argument('-i', '--input', dest="input_filename", help="the input file name")    
    parser.add_argument('-o', '--output', dest="output_filename", default = '', help="the output file name")
    parser.add_argument('-m', '--mode', dest="mode", type=int, default=1, help="the open mode of files")
    parser.add_argument('-l', '--log', dest="log_filename", help="the filename of the log file")
    parser.add_argument('-f', '--field', dest='field_name', help="the field name of a table")
    parser.add_argument('-q', '--query', dest='query', help="the query name")
    parser.add_argument('--index_filename', dest="index_filename", help="the index file name")
    parser.add_argument('--output_format', dest='output_format', type=int, default=0, help='the format of the output file')
    parser.add_argument('--operator', dest='operator', type=str, default='plain', help="the operator name of a filter")
    parser.add_argument('--start_n', dest="start_n", type=int, default=0, help="the start row number")
    parser.add_argument('--end_n', dest="end_n", type=int, default=0, help="the end row number")
    parser.add_argument('--tables', dest="tables", default='', help="tables to be executed")
    parser.add_argument('--block_number', dest="block_number", type=int, default=1, help="the block number to be used")
    parser.add_argument('--index_mode', dest="index_mode", type=int, default=0, help="the index mode")
    args = parser.parse_args()
    log_filename = ''
    if args.log_filename:
        log_filename = args.log_filename
    else:
        log_filename = 'puzautils.log'
    logging.basicConfig(filename= log_filename, filemode='w', level=logging.INFO, format='%(asctime)s::%(levelname)s::[%(module)s::%(funcName)s]::%(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
    logging.info('Started PuzaUtils.')
    ParserProcesser.ProcessActions(parser, args)    
    logging.info('End PuzaUtils.')